package com.zhanglu.authentication.security;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import org.springframework.stereotype.Component;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Objects;

@Slf4j
@Component
public class PreAuthenticatedProcessingFilter extends AbstractPreAuthenticatedProcessingFilter {
    @Autowired
    private TokenUtil tokenUtil;
    @Value("${spring.application.name}")
    private String serverName;

    @Autowired
    public PreAuthenticatedProcessingFilter(PreAuthUserAuthenticationManager authManager){
        setAuthenticationManager(authManager);
    }

    @Override
    protected Object getPreAuthenticatedPrincipal(HttpServletRequest httpServletRequest) {
        Object token = getPreAuthenticatedCredentials(httpServletRequest);
        if (Objects.isNull(token)) {
            return null;
        }

        AuthenticationUser user = tokenUtil.parserToken(token.toString());

        user.setUrl(httpServletRequest.getServletPath());
        user.setServerName(serverName);
        user.setMethodType(httpServletRequest.getMethod());

        return user;
    }

    @Override
    protected Object getPreAuthenticatedCredentials(HttpServletRequest httpServletRequest) {
        String token = httpServletRequest.getHeader(tokenUtil.getCOOKIE_AUTH());
        if (!Objects.isNull(token)) {
            return token;
        }
        Cookie[] cookieArr = httpServletRequest.getCookies();
        if (null == cookieArr || cookieArr.length <= 0) {
            return null;
        }
        try {
            return  Arrays.stream(cookieArr).filter(cookie -> tokenUtil.getCOOKIE_AUTH().equalsIgnoreCase(cookie.getName()))
                    .map(Cookie::getValue).findFirst().orElse(null);
        }catch (Exception e){
            return null;
        }
    }
}
